/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.aopalliance.intercept;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * Intercepts calls on an interface on its way to the target. These
 * are nested "on top" of the target.
 *
 * <p>The user should implement the {@link #invoke(MethodInvocation)}
 * method to modify the original behavior. E.g. the following class
 * implements a tracing interceptor (traces all the calls on the
 * intercepted method(s)):
 *
 * <pre class=code>
 * class TracingInterceptor implements MethodInterceptor {
 *   Object invoke(MethodInvocation i) throws Throwable {
 *     System.out.println("method "+i.getMethod()+" is called on "+
 *                        i.getThis()+" with args "+i.getArguments());
 *     Object ret=i.proceed();
 *     System.out.println("method "+i.getMethod()+" returns "+ret);
 *     return ret;
 *   }
 * }
 * </pre>
 *
 * @author Rod Johnson
 */
/*
1. 总结
 用于拦截方法调用
	它是函数式接口，只有一个 invoke 方法需要实现
	主要用于在目标方法执行前后添加额外的处理逻辑
	在 Spring AOP 中被广泛使用作为切面的核心组件
2. 内部成员
Object invoke(MethodInvocation invocation) throws Throwable
	核心拦截方法，在目标方法被调用时执行
	参数 invocation 包含了方法调用的所有信息
	需要显式调用 invocation.proceed() 来继续执行链中的下一个拦截器或目标方法
	返回值是目标方法执行的结果，可能被拦截器修改

3 相关的接口和类
 Interceptor	标记接口，用于拦截方法调用
 ├── ConstructorInterceptor  构造器拦截器，用于拦截构造器调用
 └── MethodInterceptor	方法拦截器，可以在方法调用前后执行自定义逻辑
	├── TransactionInterceptor	事务拦截器，用于处理声明式事务
	├── CacheInterceptor	缓存拦截器，用于处理缓存逻辑
	├── MethodValidationInterceptor	方法验证拦截器，用于参数验证
	├── ExposeInvocationInterceptor	暴露当前 MethodInvocation 到 ThreadLocal 的拦截器
	├── JCacheInterceptor 用于处理 JCache (JSR-107) 注解驱动的缓存操作，拦截带有 @CacheResult、@CachePut 等注解的方法
	├── OpenSessionInterceptor	主要用于 Hibernate 场景，在方法执行前打开 Hibernate Session，确保在整个方法执行过程中 Session 保持开启状态
	├── EventPublicationInterceptor	用于事件发布的拦截器
	├── RemoteInvocationTraceInterceptor	用于跟踪远程方法调用，记录远程调用的详细信息
	├── PersistenceExceptionTranslationInterceptor  用于将底层持久化框架的异常转换为 Spring 统一数据访问异常体系
	├── ConcurrencyThrottleInterceptor	用于限制并发访问，控制同时执行的目标方法数量，防止系统过载
	├── MBeanClientInterceptor	用于与 JMX MBean 进行交互，可以调用 MBean 上的操作或获取属性值
	│     └──  MBeanProxyFactoryBean	用于创建 MBean 的代理工厂 bean，简化 MBean 客户端的使用
	├── JaxWsPortClientInterceptor	用于处理 JAX-WS Web Service 客户端调用
	│     └──  JaxWsPortProxyFactoryBean	用于创建 JAX-WS Port 的代理工厂 bean，简化 Web Service 客户端的配置和使用
	├── AsyncExecutionInterceptor	异步执行拦截器，用于异步方法调用
	│     └──  AnnotationAsyncExecutionInterceptor	处理 @Async 注解的拦截器
	├── AspectJAfterThrowingAdvice
	├── AspectJAfterReturningAdvice
	├── AspectJAfterAdvice
	├── AspectJMethodBeforeAdvice
	├── AspectJAroundAdvice
	├── AfterReturningAdviceInterceptor	（拦截器适配器）将 AfterReturningAdvice 适配为 MethodInterceptor
	├── ThrowsAdviceInterceptor	（拦截器适配器）将 AfterReturningAdvice 适配为 MethodInterceptor
	├── MethodBeforeAdviceInterceptor	（拦截器适配器）将 MethodBeforeAdvice 适配为 MethodInterceptor
	├── IntroductionInterceptor
	│     ├── DelegatePerTargetObjectIntroductionInterceptor
	│     └──  DelegatingIntroductionInterceptor
	└── ...

	其他相关的接口和类
		Interceptor: 顶层接口，定义了所有拦截器的基本概念
		MethodInterceptor: 专门用于方法级别的拦截，是最常用的拦截器类型
		MethodInvocation: 表示一个方法调用的连接点，包含了方法执行的所有上下文信息
		Joinpoint: 更通用的连接点概念，MethodInvocation 是其子接口

	如下2者的区别
		org.aopalliance.intercept.MethodInterceptor  AOP Alliance 标准接口，是 Java AOP 的通用标准
		org.springframework.cglib.proxy.MethodInterceptor 属于 CGLIB 框架，是 Spring 集成的字节码生成库
		1. 所属框架不同
		 前者 属于 AOP Alliance 标准接口，是 Java AOP 的通用标准
		 后者 属于spring-cglib-repack库，是 Spring 集成的字节码生成库，和cglib相关
		2. 设计目的不同
		AOP Alliance MethodInterceptor：
			专为 AOP 场景设计
			是 Spring AOP 默认采用的标准接口
			更符合面向切面编程的概念
		CGLIB MethodInterceptor：
			主要用于一般性的方法拦截
			是 CGLIB 库原生提供的拦截机制
			更偏向于通用的代理需求
		3. 在 Spring 中的应用
			Spring AOP 优先使用 AOP Alliance 的 MethodInterceptor
			当需要强制使用 CGLIB 代理时，Spring 内部会进行适配转换
			通常建议使用 AOP Alliance 版本以保持更好的兼容性和标准性



4. 使用场景
	日志记录: 在方法执行前后记录日志信息
	性能监控: 记录方法执行时间，进行性能分析
	事务管理: 在方法执行前后处理事务的开启和提交
	安全检查: 在方法执行前进行权限验证
	缓存处理: 在方法执行前后处理缓存逻辑
	异常处理: 统一处理方法执行中的异常
5. 实际代码应用示
// 基本用法示例（来自接口文档）
class TracingInterceptor implements MethodInterceptor {
    Object invoke(MethodInvocation i) throws Throwable {
        System.out.println("method "+i.getMethod()+" is called on "+
                           i.getThis()+" with args "+i.getArguments());
        Object ret=i.proceed();
        System.out.println("method "+i.getMethod()+" returns "+ret);
        return ret;
    }
}

// Spring 中的实际应用示例
public class PerformanceMonitorInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            long endTime = System.currentTimeMillis();
            System.out.println("Method " + invocation.getMethod().getName() +
                              " took " + (endTime - startTime) + "ms");
        }
    }
}





 */
@FunctionalInterface
public interface MethodInterceptor extends Interceptor {

	/**
	 * Implement this method to perform extra treatments before and
	 * after the invocation. Polite implementations would certainly
	 * like to invoke {@link Joinpoint#proceed()}.
	 * @param invocation the method invocation joinpoint
	 * @return the result of the call to {@link Joinpoint#proceed()};
	 * might be intercepted by the interceptor
	 * @throws Throwable if the interceptors or the target object
	 * throws an exception
	 */
	@Nullable
	Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;

}
